package com.duan.common.utils;

import com.duan.common.model.FileModel;

import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * @ClassName FileZIPUtil
 * @Description
 * <p>
 *     读取目录文件 进行压缩处理
 * </p>
 * <p>
 *     文件下载demo 查看方法download
 * </p>
 * @Author duanlsh
 * @Date 2018/11/28 17:02
 * @Version 1.0
 */
public class FileZipUtil {


    /**
     * 读取文件
     * @param sourcePath
     * @param containKey
     * @return
     */
    public Map<String, List<FileModel>> read(String sourcePath, String containKey){
        return read(sourcePath, containKey, null, null);
    }

    /**
     *
     * 读取指定日期下的文件
     * @param sourcePath
     * @param containKey
     * @return
     */
    public Map<String, List<FileModel>> read(String sourcePath, String containKey, Date beginDate, Date endDate){

        File sourceFile = new File(sourcePath);
        if (!sourceFile.exists()){
            System.out.println("*************该目录不存在***************");
            throw new IllegalArgumentException("该目录不存在");
        }
        //判断是否为文件
        if (sourceFile.isFile()){
            System.out.println("*************当前输入的为文件，请更改为目录***************");
            throw new IllegalArgumentException("当前输入的为文件，请更改为目录");
        }

        //判断文件是否可以读取
        if (!sourceFile.canRead()){
            System.out.println("*************当前目录目录没有读取权限，请更改为目录***************");
            throw new IllegalArgumentException("当前目录目录没有读取权限，请更改为目录");
        }

        Map<String, List<FileModel>> sourceFileMap = new HashMap<>(16);

        if (beginDate != null && endDate != null){
            List<String> resultList = DateUtil.getBetweenDate( beginDate, endDate);

            for (String datePath : resultList){
                String sourcePathNew = sourcePath + File.separator + datePath.replace("-", "");
                readFile(sourcePath, new File(sourcePathNew), containKey, sourceFileMap);
            }
        } else {
            readFile(sourcePath, sourceFile, containKey, sourceFileMap);
        }
        return sourceFileMap;
    }

    private void readFile(String sourcePath, File sourceFile, String containKey, Map<String, List<FileModel>> sourceFileMap){
        File[] files = sourceFile.listFiles();
        if (files == null){
            return;
        }
        for (File file : files) {
            if (!file.canRead()){
                System.out.println("*************当前目录文件没有读取权限，请更改目录***************");
                continue;
            }

            if (file.isDirectory()){
                readFile(sourcePath, file,containKey, sourceFileMap);
                continue;
            }

            FileModel fileModel = null;
            if (file.getName().contains(containKey)){
                fileModel = new FileModel();
                fileModel.setFileFullPath(file.getAbsolutePath());
                fileModel.setFileParentPath(file.getParent());
                fileModel.setFileName(file.getName());
                fileModel.setFileUpdateTime(file.lastModified());
                fileModel.setFileMatchName(containKey);
                fileModel.setFileReadPath(sourcePath);
                fileModel.setFileLength(file.length());
            }


            if (fileModel != null){
                List<FileModel> specifyReadFileList = sourceFileMap.get(containKey);
                if (null == specifyReadFileList){
                    specifyReadFileList = new ArrayList<>();
                    specifyReadFileList.add(fileModel);
                    sourceFileMap.put(containKey, specifyReadFileList);
                } else {
                    specifyReadFileList.add(fileModel);
                }
            }
        }
    }


    /**
     * 执行压缩操作
     */
    public String zip(String fileOutDirectoryPath, String zipName, List<FileModel> fileModelList) throws IOException {

        if (fileModelList == null || fileModelList.isEmpty()){
            System.out.println("*******************当前文件列表没有内容，不进行压缩处理*************************");
            return null;
        }

        if (fileOutDirectoryPath == null || zipName == null || fileOutDirectoryPath.length() == 0 || zipName.length() == 0){
            System.out.println("*******************当前文件目录和文件名不能为空*************************");
            return null;
        }

        File outputDirectoryFile = new File(fileOutDirectoryPath);
        //生成输出目录
        if (!outputDirectoryFile.exists()){
            outputDirectoryFile.mkdirs();
        }

        if (!outputDirectoryFile.canWrite()){
            System.out.println("*************当前目录没有写权限，请更改为目录***************");
            return null;
        }

        long beginTime = System.currentTimeMillis();
        System.out.println("*******************开始执行压缩操作*************************");
        String writeFile = fileOutDirectoryPath + File.separator + zipName + ".zip";
        System.out.println("*********写文件到(" + writeFile + ")文件中**********");
        ZipOutputStream zipOutputStream = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(writeFile)));
        byte[] bytes = new byte[1024];
        for (FileModel fileModel : fileModelList){
            ZipEntry zipEntry = new ZipEntry(fileModel.getFileFullPath().replace(fileModel.getFileReadPath(), ""));
            zipOutputStream.putNextEntry(zipEntry);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(new FileInputStream(fileModel.getFileFullPath()));
            int read, i=0, num=0;
            System.out.println(">>>>>>>开始读取文件(" + fileModel.getFileFullPath() + ")<<<<<<<" + fileModel.getFileLength());
            while ((read = bufferedInputStream.read(bytes)) != -1){
                zipOutputStream.write(bytes,0, read);
                if (i > fileModel.getFileLength()/100 * num){
                    System.out.print(">");
                    num++;
                }
                i += read;
            }
            System.out.println();
        }
        zipOutputStream.close();

        System.out.println("*******************结束压缩操作总耗时(" + (System.currentTimeMillis() - beginTime) + " 毫秒)*************************");
        return writeFile;
    }


    public static void main(String[] args) throws IOException, ParseException {

        /**
         * testZIP文件目录结构为：
         *  - 20181119
         *      - mysql-5.7.24-winx64.zip
         *  - 20181120
         *      - mysql-8.0.13-winx64.zip
         *      - 20181121
         *          mysql-workbench-community-8.0.13-winx64.msi
         *  - 20181121
         *      - mysql-5.7.24-winx64.zip
         *      - order.txt
         *  - 20181122
         *      - mysql-5.7.24-winx64.txt
         *  - 20181123
         *      -order1.mp3
         */

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date beginDate = sdf.parse("2018-11-19");
        Date endDate = sdf.parse("2018-11-22");

        String containKey = "mysql";
        FileZipUtil fileZipUtil = new FileZipUtil();
        Map<String, List<FileModel>> readList = fileZipUtil.read("E:\\testZIP", containKey, beginDate, endDate);
        List<FileModel> fileModelList = readList.get(containKey);
        for (FileModel fileModel : fileModelList){
            System.out.println(fileModel.getFileReadPath());
            System.out.println(fileModel.getFileFullPath());
            System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
        }
        fileZipUtil.zip("E:\\testZIP1\\", containKey, readList.get(containKey));
    }


//    public void downLoad(){
//
//        @GetMapping("/download")
//        public void download(HttpServletResponse response, HttpServletRequest request) throws ParseException, IOException {
//            String beginTime = request.getParameter("b");
//            String endTime = request.getParameter("e");
//            String containKey = request.getParameter("c");
//            if (StringUtils.isEmpty(beginTime)){
//                beginTime = "2018-11-19";
//            }
//            if (StringUtils.isEmpty(endTime)){
//                endTime = "2018-11-19";
//            }
//
//            if (StringUtils.isEmpty(containKey)){
//                containKey = "mysql";
//            }
//            String fileName = "download.zip";
//            response.setContentType("application/octet-stream");
//            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
//
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
//            Date beginDate = sdf.parse(beginTime);
//            Date endDate = sdf.parse(endTime);
//
//            FileZipUtil fileZipUtil = new FileZipUtil();
//            Map<String, List<FileModel>> readList = fileZipUtil.read("E:\\testZIP", containKey, beginDate, endDate);
//            String result = fileZipUtil.zip("E:\\testZIP1\\", containKey, readList.get(containKey));
//
//            if (result != null){
//                FileInputStream fileInputStream = new FileInputStream(new File(result));
//                BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
//
//                byte[] buff = new byte[1024];
//                BufferedInputStream bis = bufferedInputStream;
//                OutputStream os = response.getOutputStream();
//                int bytesRead;
//                while (-1 != (bytesRead = bis.read(buff, 0, buff.length))){
//                    os.write(buff, 0, bytesRead);
//                    os.flush();
//                }
//                os.close();
//                bis.close();
//            }
//
//
//        }
//    }
}
